﻿using System.Linq;
using IGS.Core.Evaluators;
using IGS.Core.Systems;
using Moq;
using NUnit.Framework;

namespace IGS.Core.Tests.Evaluators
{
    public static class PairwiseForceEvaluatorTests
    {
        [TestFixture]
        public class GivenNBodySystemWithInitialConditions
        {
            [Test]
            public void WhenEvaluateIsCalledThenPairwiseShouldBeCalledBetweenAllUniqueBodyPairs()
            {
                // Arrange
                const int n = 32;
                var mockBodies = Enumerable.Range(0, n).Select(x => new Mock<IInteractable>()).ToArray();
                var bodies = mockBodies.Select(m => m.Object).ToArray();
                var system = new Mock<INBodySystem>();
                system.Setup(s => s.Length).Returns(n);

                for (var i = 0; i < n; i++)
                {
                    var index = i;
                    system.SetupGet(s => s[index]).Returns(bodies[index]);
                }

                var evaluator = new PairwiseForceEvaluator();

                // Act
                evaluator.Evaluate(system.Object);

                // Assert
                for (var i = 0; i < n; i++)
                    for (var j = i + 1; j < n; j++)
                    {
                        var local = j;
                        mockBodies[i].Verify(m => m.Pairwise(mockBodies[local].Object));
                    }
            }
        }
    }
}
